/*
 * This file is part of Advanced ABX
 *
 * Copyright 2010 Christian Uebber
 *
 * Advanced ABX is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2, as
 * published by the Free Software Foundation.
 *
 * Advanced ABX is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Advanced ABX.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.uebber.sound.abx.view;

import de.uebber.sound.abx.controller.ABXController;
import de.uebber.sound.abx.model.ABXBean;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

/**
 * @author Christian Uebber
 */
public class MainPanel implements PropertyChangeListener {

    private ABXBean data;
    private ABXController controller;
    private JFrame parent;
    private Timer timer;

    private JButton playButton;
    private JButton stopButton;
    private JButton xIsAButton;
    private JButton xIsBButton;
    private JButton trackAButton;
    private JButton trackBButton;
    private JButton trackXButton;
    private JTextArea messageTextArea;
    private JPanel rootPanel;
    private JSlider positionSlider;
    private JButton pauseButton;
    private JTextField numberOfRoundsTextField;
    private JTextField transitionLengthTextField;
    private JPanel tracksPanel;
    private JPanel transportButtonsPanel;
    private JPanel transportPanel;
    private JButton resetButton;
    private JPanel abxPanel;
    private JButton fileAButton;
    private JButton fileBButton;
    private JButton readFilesButton;
    private JLabel fileALabel;
    private JLabel fileBLabel;

    public static void main(String[] args) {
        for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(laf.getName())) {
                try {
                    UIManager.setLookAndFeel(laf.getClassName());
                } catch (Exception e) {
                    // Just ignore and use the default layout
                }
            }
        }

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame;
                frame = new JFrame("Advanced ABX");
                frame.setContentPane(new MainPanel(new ABXController(), frame).rootPanel);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    public MainPanel(ABXController controller, JFrame parent) {
        this.controller = controller;
        this.parent = parent;
        data = controller.getBean();
        data.addPropertyChangeListener(this);
        messageTextArea.setFont(Font.decode(Font.MONOSPACED));
        initPositionSliderTimer();

        update();


        trackAButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.switchToA();
            }
        });
        trackBButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.switchToB();
            }
        });
        trackXButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.switchToX();
            }
        });
        playButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.play();
                timer.start();
            }
        });
        pauseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.pause();
                timer.stop();
            }
        });
        stopButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.stop();
                timer.stop();
                positionSlider.setValue(0);
            }
        });
        xIsAButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.decideXisA();
            }
        });
        xIsBButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.decideXisB();
            }
        });
        numberOfRoundsTextField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.data.setNumberOfRounds(Integer.parseInt(numberOfRoundsTextField.getText()));
            }
        });
        transitionLengthTextField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.data.setTransitionLength(Integer.parseInt(transitionLengthTextField.getText()));
            }
        });
        resetButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.resetTest();
            }
        });
        fileAButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fc = new JFileChooser();
                fc.setDialogType(JFileChooser.FILES_ONLY);
                fc.showOpenDialog(rootPanel);
                MainPanel.this.data.setFileA(fc.getSelectedFile());
            }
        });
        fileBButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fc = new JFileChooser();
                fc.setDialogType(JFileChooser.FILES_ONLY);
                fc.showOpenDialog(rootPanel);
                MainPanel.this.data.setFileB(fc.getSelectedFile());
            }
        });
        readFilesButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MainPanel.this.controller.readFiles();
            }
        });
        positionSlider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                MainPanel.this.controller.setMillisecondPosition(positionSlider.getValue());
            }
        });
    }

    private void update() {
        trackAButton.setEnabled(data.isReadyForPlayback());
        trackBButton.setEnabled(data.isReadyForPlayback());
        trackXButton.setEnabled(data.isReadyForPlayback());
        playButton.setEnabled(data.isReadyForPlayback());
        pauseButton.setEnabled(data.isReadyForPlayback());
        stopButton.setEnabled(data.isReadyForPlayback());
        positionSlider.setEnabled(data.isReadyForPlayback());
        xIsAButton.setEnabled(data.isReadyForTesting());
        xIsBButton.setEnabled(data.isReadyForTesting());
        resetButton.setEnabled(data.isReadyForPlayback());

        numberOfRoundsTextField.setEnabled(data.isModifiable() && data.isReadyForPlayback());
        transitionLengthTextField.setEnabled(data.isModifiable() && data.isReadyForPlayback());

        readFilesButton.setEnabled(data.isReadyForReading());

        fileALabel.setText(data.getFileALabel());
        fileBLabel.setText(data.getFileBLabel());

        positionSlider.setMaximum(data.getTrackMillisecondLength());

        numberOfRoundsTextField.setText(String.valueOf(data.getNumberOfRounds()));
        transitionLengthTextField.setText(String.valueOf(data.getTransitionLength()));
        messageTextArea.setText(data.getLog());
        parent.pack();
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        update();
    }

    private void initPositionSliderTimer() {
        timer = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                positionSlider.setValue(controller.getMillisecondPosition());
            }
        });
    }

}